/*    1:     */ package com.atomikos.icatch.imp;
/*    2:     */ 
/*    3:     */ import com.atomikos.datasource.RecoverableResource;
/*    4:     */ import com.atomikos.diagnostics.Console;
/*    5:     */ import com.atomikos.finitestates.FSMEnterEvent;
/*    6:     */ import com.atomikos.finitestates.FSMEnterListener;
/*    7:     */ import com.atomikos.icatch.CompositeCoordinator;
/*    8:     */ import com.atomikos.icatch.CompositeTransaction;
/*    9:     */ import com.atomikos.icatch.Participant;
/*   10:     */ import com.atomikos.icatch.Propagation;
/*   11:     */ import com.atomikos.icatch.RecoveryCoordinator;
/*   12:     */ import com.atomikos.icatch.RecoveryService;
/*   13:     */ import com.atomikos.icatch.SubTxAwareParticipant;
/*   14:     */ import com.atomikos.icatch.SysException;
/*   15:     */ import com.atomikos.icatch.TSListener;
/*   16:     */ import com.atomikos.icatch.TransactionService;
/*   17:     */ import com.atomikos.icatch.TxState;
/*   18:     */ import com.atomikos.icatch.admin.LogControl;
/*   19:     */ import com.atomikos.icatch.imp.thread.InterruptedExceptionHelper;
/*   20:     */ import com.atomikos.icatch.system.Configuration;
/*   21:     */ import com.atomikos.persistence.LogException;
/*   22:     */ import com.atomikos.persistence.StateRecoveryManager;
/*   23:     */ import com.atomikos.util.UniqueIdMgr;
/*   24:     */ import java.io.PrintStream;
/*   25:     */ import java.util.Enumeration;
/*   26:     */ import java.util.Hashtable;
/*   27:     */ import java.util.Iterator;
/*   28:     */ import java.util.Properties;
/*   29:     */ import java.util.Stack;
/*   30:     */ import java.util.Vector;
/*   31:     */ 
/*   32:     */ public class TransactionServiceImp
/*   33:     */   implements TransactionService, FSMEnterListener, SubTxAwareParticipant, RecoveryService
/*   34:     */ {
/*   35:     */   private static final int NUMLATCHES = 97;
/*   36:     */   private long maxTimeout_;
/*   37:  76 */   private Object[] rootlatches_ = null;
/*   38:  79 */   private Hashtable tidtotxmap_ = null;
/*   39:  82 */   private Hashtable roottocoordinatormap_ = null;
/*   40:  85 */   private boolean shuttingDown_ = false;
/*   41:     */   private Object shutdownWaiter_;
/*   42:     */   private Object recoveryWaiter_;
/*   43:  95 */   private UniqueIdMgr tidmgr_ = null;
/*   44:  98 */   private StateRecoveryManager recoverymanager_ = null;
/*   45: 101 */   private boolean initialized_ = false;
/*   46:     */   private Console console_;
/*   47:     */   private LogControl control_;
/*   48:     */   private boolean otsOverride_;
/*   49:     */   private Vector listeners_;
/*   50:     */   private int maxActives_;
/*   51:     */   private String name_;
/*   52:     */   private Properties properties_;
/*   53:     */   private boolean single_threaded_2pc_;
/*   54:     */   
/*   55:     */   public TransactionServiceImp(String name, StateRecoveryManager recoverymanager, UniqueIdMgr tidmgr, Console console, long maxtimeout, int maxActives, boolean single_threaded_2pc)
/*   56:     */   {
/*   57: 155 */     this(name, recoverymanager, tidmgr, console, maxtimeout, true, maxActives, single_threaded_2pc);
/*   58:     */   }
/*   59:     */   
/*   60:     */   public TransactionServiceImp(String name, StateRecoveryManager recoverymanager, UniqueIdMgr tidmgr, Console console, long maxtimeout, boolean checkorphans, int maxActives, boolean single_threaded_2pc)
/*   61:     */   {
/*   62: 189 */     this.maxActives_ = maxActives;
/*   63: 190 */     if (!checkorphans) {
/*   64: 191 */       this.otsOverride_ = true;
/*   65:     */     } else {
/*   66: 193 */       this.otsOverride_ = false;
/*   67:     */     }
/*   68: 195 */     this.initialized_ = false;
/*   69: 196 */     this.recoverymanager_ = recoverymanager;
/*   70: 197 */     this.tidmgr_ = tidmgr;
/*   71: 198 */     this.tidtotxmap_ = new Hashtable();
/*   72: 199 */     this.shutdownWaiter_ = new Object();
/*   73: 200 */     this.recoveryWaiter_ = new Object();
/*   74: 201 */     this.roottocoordinatormap_ = new Hashtable();
/*   75: 202 */     this.rootlatches_ = new Object[97];
/*   76: 203 */     for (int i = 0; i < 97; i++) {
/*   77: 204 */       this.rootlatches_[i] = new Object();
/*   78:     */     }
/*   79: 206 */     this.console_ = console;
/*   80: 207 */     this.maxTimeout_ = maxtimeout;
/*   81: 208 */     this.name_ = name;
/*   82: 209 */     this.listeners_ = new Vector();
/*   83: 210 */     this.single_threaded_2pc_ = single_threaded_2pc;
/*   84:     */   }
/*   85:     */   
/*   86:     */   protected Object getLatch(String root)
/*   87:     */   {
/*   88: 222 */     return this.rootlatches_[java.lang.Math.abs(root.toString().hashCode() % 97)];
/*   89:     */   }
/*   90:     */   
/*   91:     */   void setTidToTx(String tid, CompositeTransaction ct)
/*   92:     */     throws IllegalStateException
/*   93:     */   {
/*   94: 240 */     synchronized (this.tidtotxmap_)
/*   95:     */     {
/*   96: 241 */       if (this.tidtotxmap_.containsKey(tid.intern())) {
/*   97: 242 */         throw new IllegalStateException("Already mapped: " + tid);
/*   98:     */       }
/*   99: 243 */       this.tidtotxmap_.put(tid.intern(), ct);
/*  100:     */       
/*  101:     */ 
/*  102: 246 */       ct.addSubTxAwareParticipant(this);
/*  103:     */     }
/*  104:     */   }
/*  105:     */   
/*  106:     */   Vector getCoordinatorImpVector()
/*  107:     */   {
/*  108: 260 */     Vector ret = new Vector();
/*  109: 261 */     Enumeration tids = this.roottocoordinatormap_.keys();
/*  110: 262 */     while (tids.hasMoreElements())
/*  111:     */     {
/*  112: 263 */       String next = (String)tids.nextElement();
/*  113: 264 */       CoordinatorImp c = getCoordinatorImp(next);
/*  114: 265 */       if (c != null) {
/*  115: 269 */         ret.addElement(c);
/*  116:     */       }
/*  117:     */     }
/*  118: 272 */     return ret;
/*  119:     */   }
/*  120:     */   
/*  121:     */   private void notifyListeners(boolean init, boolean before)
/*  122:     */   {
/*  123: 288 */     Enumeration enumm = this.listeners_.elements();
/*  124: 289 */     while (enumm.hasMoreElements())
/*  125:     */     {
/*  126: 290 */       TSListener l = (TSListener)enumm.nextElement();
/*  127:     */       try
/*  128:     */       {
/*  129: 292 */         if (init) {
/*  130: 293 */           l.init(before, this.properties_);
/*  131:     */         } else {
/*  132: 295 */           l.shutdown(before);
/*  133:     */         }
/*  134:     */       }
/*  135:     */       catch (Exception e)
/*  136:     */       {
/*  137: 299 */         Configuration.logWarning("Error in TSListener", e);
/*  138:     */       }
/*  139:     */     }
/*  140:     */   }
/*  141:     */   
/*  142:     */   private void removeCoordinator(CompositeCoordinator coord)
/*  143:     */   {
/*  144: 315 */     synchronized (this.shutdownWaiter_)
/*  145:     */     {
/*  146: 316 */       synchronized (getLatch(coord.getCoordinatorId().intern()))
/*  147:     */       {
/*  148: 318 */         this.roottocoordinatormap_.remove(coord.getCoordinatorId().intern());
/*  149:     */       }
/*  150: 322 */       if (this.roottocoordinatormap_.isEmpty()) {
/*  151: 323 */         this.shutdownWaiter_.notifyAll();
/*  152:     */       }
/*  153:     */     }
/*  154:     */   }
/*  155:     */   
/*  156:     */   private void removeTransaction(CompositeTransaction ct)
/*  157:     */   {
/*  158: 338 */     if (ct == null) {
/*  159: 339 */       return;
/*  160:     */     }
/*  161: 340 */     this.tidtotxmap_.remove(ct.getTid().intern());
/*  162:     */   }
/*  163:     */   
/*  164:     */   private CompositeTransactionImp createCT(String tid, CoordinatorImp coordinator, Stack lineage, boolean serial)
/*  165:     */     throws SysException
/*  166:     */   {
/*  167: 354 */     if (Configuration.isDebugLoggingEnabled()) {
/*  168: 354 */       Configuration.logDebug("Creating composite transaction: " + tid);
/*  169:     */     }
/*  170: 355 */     CompositeTransactionImp ct = new CompositeTransactionImp(this, lineage, tid, serial, coordinator);
/*  171:     */     
/*  172:     */ 
/*  173: 358 */     setTidToTx(ct.getTid(), ct);
/*  174: 359 */     return ct;
/*  175:     */   }
/*  176:     */   
/*  177:     */   private CoordinatorImp createCC(RecoveryCoordinator adaptor, String root, boolean checkOrphans, boolean heuristic_commit, long timeout)
/*  178:     */   {
/*  179: 389 */     CoordinatorImp cc = null;
/*  180: 391 */     if (timeout > this.maxTimeout_)
/*  181:     */     {
/*  182: 392 */       timeout = this.maxTimeout_;
/*  183:     */       
/*  184: 394 */       Configuration.logWarning("Attempt to create a transaction with a timeout that exceeds com.atomikos.icatch.max_timeout - truncating to: " + this.maxTimeout_);
/*  185:     */     }
/*  186: 400 */     synchronized (this.shutdownWaiter_)
/*  187:     */     {
/*  188: 403 */       if (this.shuttingDown_) {
/*  189: 404 */         throw new IllegalStateException("Server is shutting down...");
/*  190:     */       }
/*  191: 406 */       if (this.otsOverride_) {
/*  192: 408 */         checkOrphans = false;
/*  193:     */       }
/*  194: 410 */       cc = new CoordinatorImp(root, adaptor, this.console_, heuristic_commit, timeout, checkOrphans, this.single_threaded_2pc_);
/*  195:     */       
/*  196:     */ 
/*  197:     */ 
/*  198: 414 */       this.recoverymanager_.register(cc);
/*  199: 418 */       synchronized (getLatch(root.intern()))
/*  200:     */       {
/*  201: 419 */         this.roottocoordinatormap_.put(root.intern(), cc);
/*  202:     */       }
/*  203: 421 */       startlistening(cc);
/*  204:     */     }
/*  205: 424 */     return cc;
/*  206:     */   }
/*  207:     */   
/*  208:     */   private void startlistening(CoordinatorImp coordinator)
/*  209:     */   {
/*  210: 437 */     Hashtable forgetStates = new Hashtable();
/*  211:     */     
/*  212:     */ 
/*  213:     */ 
/*  214:     */ 
/*  215:     */ 
/*  216:     */ 
/*  217:     */ 
/*  218:     */ 
/*  219:     */ 
/*  220:     */ 
/*  221:     */ 
/*  222:     */ 
/*  223: 450 */     forgetStates.put(TxState.TERMINATED, new Object());
/*  224:     */     
/*  225: 452 */     Object[] finalStates = coordinator.getFinalStates();
/*  226: 453 */     for (int i = 0; i < finalStates.length; i++) {
/*  227: 454 */       forgetStates.put(finalStates[i], new Object());
/*  228:     */     }
/*  229: 457 */     Enumeration enumm = forgetStates.keys();
/*  230: 459 */     while (enumm.hasMoreElements())
/*  231:     */     {
/*  232: 460 */       Object state = enumm.nextElement();
/*  233: 461 */       coordinator.addFSMEnterListener(this, state);
/*  234:     */     }
/*  235: 466 */     if (forgetStates.contains(coordinator.getState())) {
/*  236: 467 */       removeCoordinator(coordinator);
/*  237:     */     }
/*  238:     */   }
/*  239:     */   
/*  240:     */   private CoordinatorImp getCoordinatorImp(String root)
/*  241:     */     throws SysException
/*  242:     */   {
/*  243: 473 */     root = root.intern();
/*  244: 474 */     Stack errors = new Stack();
/*  245: 475 */     if (!this.initialized_) {
/*  246: 476 */       throw new IllegalStateException("Not initialized");
/*  247:     */     }
/*  248: 478 */     CoordinatorImp cc = null;
/*  249: 479 */     synchronized (this.shutdownWaiter_)
/*  250:     */     {
/*  251: 483 */       synchronized (getLatch(root))
/*  252:     */       {
/*  253: 484 */         cc = (CoordinatorImp)this.roottocoordinatormap_.get(root.intern());
/*  254: 486 */         if (cc == null)
/*  255:     */         {
/*  256:     */           try
/*  257:     */           {
/*  258: 489 */             cc = (CoordinatorImp)this.recoverymanager_.recover(root);
/*  259:     */           }
/*  260:     */           catch (LogException le)
/*  261:     */           {
/*  262: 491 */             errors.push(le);
/*  263: 492 */             throw new SysException("Error in getting coordinator: " + le.getMessage(), errors);
/*  264:     */           }
/*  265: 496 */           if (cc != null)
/*  266:     */           {
/*  267: 497 */             startlistening(cc);
/*  268: 498 */             this.roottocoordinatormap_.put(root.intern(), cc);
/*  269:     */           }
/*  270:     */         }
/*  271:     */       }
/*  272:     */     }
/*  273: 504 */     return cc;
/*  274:     */   }
/*  275:     */   
/*  276:     */   protected String createTid()
/*  277:     */     throws SysException
/*  278:     */   {
/*  279: 515 */     return this.tidmgr_.get();
/*  280:     */   }
/*  281:     */   
/*  282:     */   protected StateRecoveryManager getStateRecoveryManager()
/*  283:     */   {
/*  284: 526 */     return this.recoverymanager_;
/*  285:     */   }
/*  286:     */   
/*  287:     */   protected synchronized void recoverCoordinators()
/*  288:     */     throws SysException
/*  289:     */   {
/*  290: 539 */     Stack errors = new Stack();
/*  291:     */     try
/*  292:     */     {
/*  293: 543 */       Vector recovered = this.recoverymanager_.recover();
/*  294: 544 */       Enumeration enumm = recovered.elements();
/*  295: 545 */       while (enumm.hasMoreElements())
/*  296:     */       {
/*  297: 546 */         CoordinatorImp coord = (CoordinatorImp)enumm.nextElement();
/*  298: 547 */         synchronized (getLatch(coord.getCoordinatorId().intern()))
/*  299:     */         {
/*  300: 548 */           this.roottocoordinatormap_.put(coord.getCoordinatorId().intern(), coord);
/*  301:     */         }
/*  302: 551 */         startlistening(coord);
/*  303:     */       }
/*  304:     */     }
/*  305:     */     catch (Exception e)
/*  306:     */     {
/*  307: 556 */       Configuration.logWarning("Error in recoverCoordinators", e);
/*  308: 557 */       errors.push(e);
/*  309: 558 */       throw new SysException("Error in recoverCoordinators: " + e.getMessage(), errors);
/*  310:     */     }
/*  311:     */   }
/*  312:     */   
/*  313:     */   public String getName()
/*  314:     */   {
/*  315: 566 */     return this.name_;
/*  316:     */   }
/*  317:     */   
/*  318:     */   public void recover()
/*  319:     */   {
/*  320: 578 */     if (Configuration.getTransactionService() == null)
/*  321:     */     {
/*  322: 579 */       Configuration.installTransactionService(this);
/*  323: 580 */       Configuration.installRecoveryService(this);
/*  324:     */     }
/*  325: 586 */     if (!this.initialized_)
/*  326:     */     {
/*  327: 589 */       notifyListeners(true, true);
/*  328: 590 */       this.initialized_ = true;
/*  329:     */     }
/*  330: 593 */     synchronized (this.recoveryWaiter_)
/*  331:     */     {
/*  332:     */       try
/*  333:     */       {
/*  334: 605 */         Vector coordinators = getCoordinatorImpVector();
/*  335: 606 */         Iterator it = coordinators.iterator();
/*  336: 607 */         while (it.hasNext())
/*  337:     */         {
/*  338: 608 */           CoordinatorImp coord = (CoordinatorImp)it.next();
/*  339:     */           try
/*  340:     */           {
/*  341: 610 */             if ((!coord.recover()) && (this.console_ != null)) {
/*  342: 611 */               this.console_.println("Coordinator not recoverable: " + coord.getCoordinatorId());
/*  343:     */             }
/*  344:     */           }
/*  345:     */           catch (Exception e)
/*  346:     */           {
/*  347: 620 */             Configuration.logWarning("Coordinator not recoverable: " + coord.getCoordinatorId(), e);
/*  348:     */           }
/*  349:     */         }
/*  350: 629 */         Enumeration reslist = Configuration.getResources();
/*  351: 631 */         while (reslist.hasMoreElements())
/*  352:     */         {
/*  353: 632 */           RecoverableResource res = (RecoverableResource)reslist.nextElement();
/*  354:     */           try
/*  355:     */           {
/*  356: 635 */             res.endRecovery();
/*  357:     */           }
/*  358:     */           catch (Exception error)
/*  359:     */           {
/*  360: 637 */             Configuration.logWarning("ERROR IN RECOVERY", error);
/*  361:     */           }
/*  362:     */         }
/*  363:     */       }
/*  364:     */       catch (Exception e)
/*  365:     */       {
/*  366: 644 */         Configuration.logWarning("Error in recover: " + e.getClass().getName() + e.getMessage(), e);
/*  367:     */         
/*  368:     */ 
/*  369: 647 */         Stack errors = new Stack();
/*  370: 648 */         errors.push(e);
/*  371: 649 */         throw new SysException("Error in recovering: " + e.getMessage(), errors);
/*  372:     */       }
/*  373:     */     }
/*  374:     */   }
/*  375:     */   
/*  376:     */   public LogControl getLogControl()
/*  377:     */   {
/*  378: 666 */     return this.control_;
/*  379:     */   }
/*  380:     */   
/*  381:     */   public CompositeCoordinator getCompositeCoordinator(String root)
/*  382:     */     throws SysException
/*  383:     */   {
/*  384: 676 */     return getCoordinatorImp(root);
/*  385:     */   }
/*  386:     */   
/*  387:     */   public void addTSListener(TSListener listener)
/*  388:     */     throws IllegalStateException
/*  389:     */   {
/*  390: 692 */     if (!this.listeners_.contains(listener))
/*  391:     */     {
/*  392: 693 */       this.listeners_.addElement(listener);
/*  393: 694 */       if (this.initialized_) {
/*  394: 695 */         listener.init(false, this.properties_);
/*  395:     */       }
/*  396: 697 */       if (Configuration.isDebugLoggingEnabled()) {
/*  397: 697 */         Configuration.logDebug("Added TSListener: " + listener);
/*  398:     */       }
/*  399:     */     }
/*  400:     */   }
/*  401:     */   
/*  402:     */   public void removeTSListener(TSListener listener)
/*  403:     */   {
/*  404: 710 */     this.listeners_.removeElement(listener);
/*  405: 711 */     if (Configuration.isDebugLoggingEnabled()) {
/*  406: 711 */       Configuration.logDebug("Removed TSListener: " + listener);
/*  407:     */     }
/*  408:     */   }
/*  409:     */   
/*  410:     */   public synchronized void init(Properties properties)
/*  411:     */     throws SysException
/*  412:     */   {
/*  413: 721 */     Stack errors = new Stack();
/*  414: 722 */     this.properties_ = properties;
/*  415:     */     try
/*  416:     */     {
/*  417: 725 */       this.recoverymanager_.init();
/*  418:     */     }
/*  419:     */     catch (LogException le)
/*  420:     */     {
/*  421: 727 */       errors.push(le);
/*  422: 728 */       throw new SysException("Error in init: " + le.getMessage(), errors);
/*  423:     */     }
/*  424: 731 */     recoverCoordinators();
/*  425:     */     
/*  426:     */ 
/*  427:     */ 
/*  428:     */ 
/*  429: 736 */     this.shuttingDown_ = false;
/*  430: 737 */     this.control_ = new LogControlImp(this);
/*  431:     */     
/*  432:     */ 
/*  433:     */ 
/*  434: 741 */     recover();
/*  435: 742 */     notifyListeners(true, false);
/*  436:     */   }
/*  437:     */   
/*  438:     */   public Participant getParticipant(String root)
/*  439:     */     throws SysException
/*  440:     */   {
/*  441: 751 */     return getCoordinatorImp(root);
/*  442:     */   }
/*  443:     */   
/*  444:     */   public void entered(FSMEnterEvent event)
/*  445:     */   {
/*  446: 760 */     CoordinatorImp cc = (CoordinatorImp)event.getSource();
/*  447: 761 */     Object state = event.getState();
/*  448:     */     
/*  449:     */ 
/*  450:     */ 
/*  451: 765 */     removeCoordinator(cc);
/*  452:     */   }
/*  453:     */   
/*  454:     */   public void committed(CompositeTransaction tx)
/*  455:     */   {
/*  456: 777 */     removeTransaction(tx);
/*  457:     */   }
/*  458:     */   
/*  459:     */   public void rolledback(CompositeTransaction tx)
/*  460:     */   {
/*  461: 788 */     removeTransaction(tx);
/*  462:     */   }
/*  463:     */   
/*  464:     */   public CompositeTransaction getCompositeTransaction(String tid)
/*  465:     */   {
/*  466: 798 */     CompositeTransaction ret = null;
/*  467: 800 */     synchronized (this.tidtotxmap_)
/*  468:     */     {
/*  469: 801 */       ret = (CompositeTransaction)this.tidtotxmap_.get(tid.intern());
/*  470:     */     }
/*  471: 804 */     return ret;
/*  472:     */   }
/*  473:     */   
/*  474:     */   CompositeTransaction createSubTransaction(CompositeTransaction parent)
/*  475:     */   {
/*  476: 817 */     CompositeTransactionImp ret = null;
/*  477: 818 */     Stack lineage = (Stack)parent.getLineage().clone();
/*  478: 819 */     lineage.push(parent);
/*  479: 820 */     String tid = this.tidmgr_.get();
/*  480: 821 */     CoordinatorImp ccParent = (CoordinatorImp)parent.getCompositeCoordinator();
/*  481:     */     
/*  482:     */ 
/*  483:     */ 
/*  484: 825 */     CoordinatorImp cc = createCC(null, tid, false, ccParent.prefersHeuristicCommit(), parent.getTimeout());
/*  485: 827 */     if ((ccParent.isRecoverableWhileActive() != null) && (ccParent.isRecoverableWhileActive().booleanValue())) {
/*  486: 830 */       cc.setRecoverableWhileActive();
/*  487:     */     }
/*  488: 832 */     ret = createCT(tid, cc, lineage, parent.isSerial());
/*  489: 833 */     ret.localRoot_ = false;
/*  490: 834 */     return ret;
/*  491:     */   }
/*  492:     */   
/*  493:     */   public synchronized CompositeTransaction recreateCompositeTransaction(Propagation context, boolean orphancheck, boolean heur_commit)
/*  494:     */     throws SysException
/*  495:     */   {
/*  496: 846 */     if (!this.initialized_) {
/*  497: 847 */       throw new IllegalStateException("Not initialized");
/*  498:     */     }
/*  499: 849 */     if ((this.maxActives_ >= 0) && (this.tidtotxmap_.size() >= this.maxActives_)) {
/*  500: 850 */       throw new IllegalStateException("Max number of active transactions reached:" + this.maxActives_);
/*  501:     */     }
/*  502: 853 */     Stack errors = new Stack();
/*  503: 854 */     CoordinatorImp cc = null;
/*  504: 855 */     CompositeTransaction ct = null;
/*  505:     */     try
/*  506:     */     {
/*  507: 858 */       String tid = this.tidmgr_.get();
/*  508: 859 */       boolean serial = context.isSerial();
/*  509: 860 */       Stack lineage = context.getLineage();
/*  510: 861 */       if (lineage.empty()) {
/*  511: 862 */         throw new SysException("Empty lineage in propagation: empty lineage");
/*  512:     */       }
/*  513: 864 */       Stack tmp = new Stack();
/*  514: 866 */       while (!lineage.empty()) {
/*  515: 867 */         tmp.push(lineage.pop());
/*  516:     */       }
/*  517: 870 */       CompositeTransaction root = (CompositeTransaction)tmp.peek();
/*  518: 872 */       while (!tmp.empty()) {
/*  519: 873 */         lineage.push(tmp.pop());
/*  520:     */       }
/*  521: 876 */       CompositeTransaction parent = (CompositeTransaction)lineage.peek();
/*  522: 878 */       synchronized (this.shutdownWaiter_)
/*  523:     */       {
/*  524: 879 */         synchronized (getLatch(root.getTid()))
/*  525:     */         {
/*  526: 880 */           cc = getCoordinatorImp(root.getTid());
/*  527: 881 */           if (cc == null)
/*  528:     */           {
/*  529: 882 */             RecoveryCoordinator coord = parent.getCompositeCoordinator().getRecoveryCoordinator();
/*  530:     */             
/*  531:     */ 
/*  532: 885 */             cc = createCC(coord, root.getTid(), orphancheck, heur_commit, context.getTimeOut());
/*  533:     */           }
/*  534: 888 */           cc.incLocalSiblingCount();
/*  535:     */         }
/*  536:     */       }
/*  537: 891 */       ct = createCT(tid, cc, lineage, serial);
/*  538:     */     }
/*  539:     */     catch (Exception e)
/*  540:     */     {
/*  541: 894 */       errors.push(e);
/*  542: 895 */       e.printStackTrace();
/*  543: 896 */       throw new SysException("Error in recreate.", errors);
/*  544:     */     }
/*  545: 899 */     return ct;
/*  546:     */   }
/*  547:     */   
/*  548:     */   public synchronized void shutdown(boolean force)
/*  549:     */     throws SysException, IllegalStateException
/*  550:     */   {
/*  551: 909 */     Stack errors = new Stack();
/*  552: 910 */     boolean wasShuttingDown = false;
/*  553: 911 */     if (Configuration.isDebugLoggingEnabled()) {
/*  554: 911 */       Configuration.logDebug("Transaction Service: Entering shutdown ( " + force + " )...");
/*  555:     */     }
/*  556: 917 */     if ((!wasShuttingDown) && (force))
/*  557:     */     {
/*  558: 925 */       Enumeration enumm = this.roottocoordinatormap_.keys();
/*  559: 926 */       while (enumm.hasMoreElements())
/*  560:     */       {
/*  561: 927 */         String tid = (String)enumm.nextElement();
/*  562: 928 */         Configuration.logDebug("Transaction Service: Stopping thread for root " + tid + "...");
/*  563:     */         
/*  564:     */ 
/*  565: 931 */         CoordinatorImp c = (CoordinatorImp)this.roottocoordinatormap_.get(tid);
/*  566: 933 */         if (c != null) {
/*  567: 935 */           c.dispose();
/*  568:     */         }
/*  569: 937 */         Configuration.logDebug("Transaction Service: Thread stopped.");
/*  570:     */       }
/*  571:     */     }
/*  572: 943 */     synchronized (this.shutdownWaiter_)
/*  573:     */     {
/*  574: 944 */       Configuration.logDebug("Transaction Service: Shutdown acquired lock on waiter.");
/*  575:     */       
/*  576: 946 */       wasShuttingDown = this.shuttingDown_;
/*  577: 947 */       this.shuttingDown_ = true;
/*  578: 959 */       while ((!this.roottocoordinatormap_.isEmpty()) && (!force)) {
/*  579:     */         try
/*  580:     */         {
/*  581: 961 */           Configuration.logWarning("Transaction Service: Waiting for non-terminated coordinators...");
/*  582:     */           
/*  583:     */ 
/*  584: 964 */           this.shutdownWaiter_.wait(this.maxTimeout_);
/*  585: 967 */           if (Configuration.isDebugLoggingEnabled()) {
/*  586: 967 */             Configuration.logDebug("Transaction Service: Purging coordinators for shutdown...");
/*  587:     */           }
/*  588: 968 */           Hashtable clone = (Hashtable)this.roottocoordinatormap_.clone();
/*  589: 969 */           Enumeration coordinatorIds = clone.keys();
/*  590: 970 */           while (coordinatorIds.hasMoreElements())
/*  591:     */           {
/*  592: 971 */             String id = (String)coordinatorIds.nextElement();
/*  593: 972 */             CoordinatorImp c = (CoordinatorImp)clone.get(id);
/*  594: 973 */             if (TxState.TERMINATED.equals(c.getState()))
/*  595:     */             {
/*  596: 974 */               if (Configuration.isDebugLoggingEnabled()) {
/*  597: 974 */                 Configuration.logDebug("Transaction Service: removing terminated coordinator: " + id);
/*  598:     */               }
/*  599: 975 */               this.roottocoordinatormap_.remove(id);
/*  600:     */             }
/*  601:     */           }
/*  602:     */         }
/*  603:     */         catch (InterruptedException inter)
/*  604:     */         {
/*  605: 982 */           InterruptedExceptionHelper.handleInterruptedException(inter);
/*  606: 983 */           errors.push(inter);
/*  607: 984 */           throw new SysException("Error in shutdown: " + inter.getMessage(), errors);
/*  608:     */         }
/*  609:     */       }
/*  610: 989 */       notifyListeners(false, true);
/*  611: 990 */       this.initialized_ = false;
/*  612: 991 */       if (!wasShuttingDown) {
/*  613:     */         try
/*  614:     */         {
/*  615: 999 */           this.recoverymanager_.close();
/*  616:     */         }
/*  617:     */         catch (LogException le)
/*  618:     */         {
/*  619:1003 */           errors.push(le);
/*  620:1004 */           le.printStackTrace();
/*  621:1005 */           throw new SysException("Error in shutdown: " + le.getMessage(), errors);
/*  622:     */         }
/*  623:     */       }
/*  624:     */     }
/*  625:1015 */     notifyListeners(false, false);
/*  626:     */   }
/*  627:     */   
/*  628:     */   public synchronized void finalize()
/*  629:     */     throws Throwable
/*  630:     */   {
/*  631:     */     try
/*  632:     */     {
/*  633:1022 */       if ((!this.shuttingDown_) && (this.initialized_)) {
/*  634:1023 */         shutdown(true);
/*  635:     */       }
/*  636:     */     }
/*  637:     */     catch (Exception e)
/*  638:     */     {
/*  639:1026 */       System.err.println("Error in GC of TransactionServiceImp");
/*  640:1027 */       System.err.println(e.getMessage());
/*  641:1028 */       e.printStackTrace();
/*  642:     */     }
/*  643:     */     finally
/*  644:     */     {
/*  645:1030 */       super.finalize();
/*  646:     */     }
/*  647:     */   }
/*  648:     */   
/*  649:     */   public RecoveryCoordinator getSuperiorRecoveryCoordinator(String root)
/*  650:     */   {
/*  651:1039 */     RecoveryCoordinator ret = null;
/*  652:1040 */     CoordinatorImp c = getCoordinatorImp(root);
/*  653:1041 */     if (c != null) {
/*  654:1042 */       ret = c.getSuperiorRecoveryCoordinator();
/*  655:     */     }
/*  656:1044 */     return ret;
/*  657:     */   }
/*  658:     */   
/*  659:     */   public CompositeTransaction createCompositeTransaction(long timeout)
/*  660:     */     throws SysException
/*  661:     */   {
/*  662:1050 */     if (!this.initialized_) {
/*  663:1051 */       throw new IllegalStateException("Not initialized");
/*  664:     */     }
/*  665:1053 */     if ((this.maxActives_ >= 0) && (this.tidtotxmap_.size() >= this.maxActives_)) {
/*  666:1054 */       throw new IllegalStateException("Max number of active transactions reached:" + this.maxActives_);
/*  667:     */     }
/*  668:1057 */     String tid = this.tidmgr_.get();
/*  669:1058 */     Stack lineage = new Stack();
/*  670:     */     
/*  671:     */ 
/*  672:     */ 
/*  673:     */ 
/*  674:1063 */     CoordinatorImp cc = createCC(null, tid, true, false, timeout);
/*  675:1064 */     CompositeTransaction ct = createCT(tid, cc, lineage, false);
/*  676:1065 */     return ct;
/*  677:     */   }
/*  678:     */ }


/* Location:           C:\myfile\mysoft\apache-maven-3.5.0-bin\apache-maven-3.5.0\myrep\com\atomikos\transactions\3.7.0\transactions-3.7.0.jar
 * Qualified Name:     com.atomikos.icatch.imp.TransactionServiceImp
 * JD-Core Version:    0.7.0.1
 */